package com.hd.common.base;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import org.springframework.util.ClassUtils;

/**
 * <p>Title:基于ibatis 的DAO基类</p>
 * <p>Description:</p>
 * <p>copyright:</p>
 * <p>Date: 2008-11-22 零点</p>
 * @version V1.0
 * @amendment history:
 */
public abstract class BaseIbatisDao extends SqlMapClientDaoSupport implements BaseDao {
    protected final Log log = LogFactory.getLog(getClass());
    
    public abstract Class getEntityClass();
    
    public Object getById(Serializable primaryKey) {
        Object object = getSqlMapClientTemplate().queryForObject(getFindQuery(), primaryKey);
        return object;
    }
    
	public void deleteById(Serializable id) {
		getSqlMapClientTemplate().update(getDeleteQuery(), id);
	}
	
    public void save(Object entity) {
		prepareObjectForSaveOrUpdate(entity);
		Object primaryKey = getSqlMapClientTemplate().insert(getInsertQuery(), entity);    	
    }
    
	public void update(Object entity) {
		prepareObjectForSaveOrUpdate(entity);
		Object primaryKey = getSqlMapClientTemplate().update(getUpdateQuery(), entity);
	}
	
	public void findByProperty(String property,Object value) {
		throw new UnsupportedOperationException();
	}

    protected void prepareObjectForSaveOrUpdate(Object o) {
        try {
            Field fieldlist[] = o.getClass().getDeclaredFields();
            for (int i = 0; i < fieldlist.length; i++) {
                Field fld = fieldlist[i];
                String fieldName = fld.getName();
                if (fieldName.equals("version")) {
                    Method setMethod = o.getClass().getMethod("setVersion", new Class[]{Integer.class});
                    Object value = o.getClass().getMethod("getVersion", null).invoke(o, null);
                    if (value == null) {
                        setMethod.invoke(o, new Object[]{new Integer(1)});
                    } else {
                        setMethod.invoke(o, new Object[]{new Integer(((Integer) value).intValue()+1)});
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Could not prepare '" + ClassUtils.getShortName(o.getClass()) + "' for insert/update");
        }
    }

    /**
     * @return Returns the select query name.
     */
    public String getSelectQuery() {
        return "get" + getEntityClass().getSimpleName() + "s";
    }

    /**
     * @return Returns the find query name.
     */
    public String getFindQuery() {
        return "get" + getEntityClass().getSimpleName();
    }

    /**
     * @return Returns the insert query name.
     */
    public String getInsertQuery() {
        return "add" + getEntityClass().getSimpleName();
    }

    /**
     * @return Returns the update query name.
     */
    public String getUpdateQuery() {
        return "update" + getEntityClass().getSimpleName();
    }

    /**
     * @return Returns the delete query name.
     */
    public String getDeleteQuery() {
        return "delete" + getEntityClass().getSimpleName();
    }

	public List findAll() {
		return getSqlMapClientTemplate().queryForList(getSelectQuery());
	}

	public boolean isUnique(Object entity, String uniquePropertyNames) {
		return false;
	}

	public void saveOrUpdate(Object entity) {
		
	}
}
